package it.antonio.ilpizze.ioc;

public abstract class ScopeFactory<T> {
	public abstract Scope<T> scope(Object keu, Class<? extends T> type);
	
	public static <T> ScopeFactory<T> fromScope(final Scope<T> scope) {
		return new ScopeFactory<T>() {

			@Override
			public Scope<T> scope(Object keu, Class<? extends T> type) {
				return scope;
			}
			
		};
	}
	public static <T> ScopeFactory<T> prototype(){
		return new ScopeFactory<T>() {

			@Override
			public Scope<T> scope(Object keu, Class<? extends T> type) {
				return  new Scope<T>() {

					@Override
					public void set(T instance) {
						
					}

					@Override
					public T get() {
						return null;
					}
					
					@Override
					public String toString() {
						return "Scope['prototype']";
					}
				};
			}
		};
	}
	
	public static <T> ScopeFactory<T> threadlocal(){
		return new ScopeFactory<T>() {

			@Override
			public Scope<T> scope(Object keu, Class<? extends T> type) {
				return  new Scope<T>() {

					private ThreadLocal<T> threadLocal = new ThreadLocal<T>();
					
					@Override
					public void set(T instance) {
						this.threadLocal.set(instance);
					}

					@Override
					public T get() {
						return threadLocal.get();
					}
					
					@Override
					public String toString() {
						return "Scope['prototype']";
					}
				};
			}
		};
	}
	
	public static <T> ScopeFactory<T> singleton(){
		return new ScopeFactory<T>() {

			@Override
			public Scope<T> scope(Object keu, Class<? extends T> type) {
				return  new Scope<T>() {

					private T instance;
					
					@Override
					public void set(T instance) {
						this.instance = instance;
					}

					@Override
					public T get() {
						return instance;
					}
					
					@Override
					public String toString() {
						return "Scope['prototype']";
					}
				};
			}
		};
	}
}
